package com.analysis.config;

import io.micrometer.core.instrument.util.NamedThreadFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.*;

/**
 * 保存信源信息
 * @Date 2025/9/3
 * @Author 蒋棒
 */
@Component
public class SaveReferenceExecutorService {
    /**
     * 默认核心线程数
     */
    private static final int DEFAULT_CORE_THREAD_COUNT = 10;

    /**
     * 默认最大线程数
     */
    private static final int DEFAULT_MAX_THREAD_COUNT = 20;

    /**
     * 空闲线程存活时间，单位毫秒，如果 getMaxThreadCount() > getCoreThreadCount() ,这个时间建议设置大于0
     * 默认2秒
     */
    private static final int DEFAULT_KEEP_ALIVE_TIME = 1000 * 60 * 2;

    protected ExecutorService threadPool;

    @PostConstruct
    public void startup() {
        threadPool = new ThreadPoolExecutor(
                getCoreThreadCount(),
                getMaxThreadCount(),
                getKeepAliveTime(), TimeUnit.MILLISECONDS,
                getWorkQueue(),
                getFactory(),
                getRejectPolicy()
        );
    }

    @PreDestroy
    public void shutdown() {
        if (null != threadPool) {
            threadPool.shutdownNow();
        }
    }

    /**
     * 如果任务能快速结束，可以适当大一点
     */
    protected int getCoreThreadCount() {
        return DEFAULT_CORE_THREAD_COUNT;
    }

    protected int getMaxThreadCount() {
        return DEFAULT_MAX_THREAD_COUNT;
    }

    /**
     * 核心数之外的线程存活时间：2min
     */
    protected int getKeepAliveTime() {
        return DEFAULT_KEEP_ALIVE_TIME;
    }

    /**
     * 有界阻塞队列：容量大小暂定为10
     */
    protected BlockingQueue<Runnable> getWorkQueue() {
        return new LinkedBlockingQueue<Runnable>(200);
    }

    /**
     * 获取线程池阻塞时拒绝策略
     * 默认策略：哪个线程发起的调度，就由哪个的线程来执行
     */
    protected RejectedExecutionHandler getRejectPolicy() {
        return new ThreadPoolExecutor.CallerRunsPolicy();
    }

    /**
     * 线程工厂
     */
    protected ThreadFactory getFactory() {
        return new NamedThreadFactory("save_reference_thread_pool_");
    }


    public ExecutorService getThreadPool() {
        return threadPool;
    }

}
